package com.alinesno.infra.base.search.interceptor;

import com.alinesno.infra.base.search.entity.DatasetClientEntity;
import com.alinesno.infra.base.search.service.IDatasetClientService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.lang.exception.RpcServiceRuntimeException;

/**
 * API密钥验证切面
 * 拦截带有@ApiKeyRequired注解的方法
 */
@Slf4j
@Aspect
@Component
public class DatasetApiKeyAspect {

    @Autowired
    private IDatasetClientService datasetClientService;

    // 定义切入点：拦截所有带有@ApiKeyRequired注解的方法
    @Pointcut("@annotation(apiKeyRequired)")
    public void pointcut(DatasetApiKeyRequired apiKeyRequired) {
    }

    // 前置通知：在方法执行前进行密钥验证
    @Before("pointcut(apiKeyRequired)")
    public void doBefore(DatasetApiKeyRequired apiKeyRequired) {
        // 获取当前请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            throw new RpcServiceRuntimeException("无法获取请求上下文");
        }
        HttpServletRequest request = attributes.getRequest();

        // 从请求头获取API密钥
        String apiKey = request.getHeader("Dataset-API-Key");
        if (apiKey == null || apiKey.trim().isEmpty()) {
            throw new RpcServiceRuntimeException("请求头缺少Dataset-API-Key参数");
        }

        // 验证密钥是否有效（存在且启用）
        DatasetClientEntity client = datasetClientService.getOne(
                new LambdaQueryWrapper<DatasetClientEntity>()
                        .eq(DatasetClientEntity::getApiKey, apiKey)
                        .eq(DatasetClientEntity::getKeyStatus, 1) // 1-启用状态
        );

        if (client == null) {
            log.warn("无效的API密钥：{}", apiKey);
            throw new RpcServiceRuntimeException("无效的API密钥或密钥已禁用");
        }

        // 验证通过，可将客户端信息存入请求属性（后续方法可获取）
        request.setAttribute("clientId", client.getId());
        request.setAttribute("clientName", client.getClientName());
        log.debug("API密钥验证通过，客户端ID：{}", client.getId());
    }
}